package com.example.spark.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.spark.dao.FilesDao;
import com.example.spark.dao.UserDao;
import com.example.spark.entity.Files;
import com.example.spark.entity.User;
import com.example.spark.entity.dto.PaginationDTO;
import com.example.spark.entity.result.CommonResult;
import com.example.spark.service.FilesService;
import com.example.spark.service.minio.MinioCloudStorageService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class FilesServiceImpl extends ServiceImpl<FilesDao, Files> implements FilesService {
    @Resource
    MinioCloudStorageService minIoService;

    @Autowired
    private FilesDao filesDao;

    @Autowired
    private UserDao userDao;

    // 新增（投递）简历
    public CommonResult insertIntoFiles(MultipartFile file, Long id) throws IOException {
        Files fileById = filesDao.selectOne(query().getWrapper().eq("user_id", id));
        if (fileById == null) {
            // 根据id查询到真实姓名作为简历的文件名
            String name = filesDao.selectUserName(id);
            // getOriginalFileName方法获取的是文件的完整名称，包括文件名称+文件拓展名
            String extension = FilenameUtils.getExtension(file.getOriginalFilename()); //后缀
            // 上传文件并获取文件存储路径
            String url = minIoService.uploadFileSuffix(file.getBytes(), extension, name, file.getContentType());
            // 创建简历实体类用于插入数据
            Files files = new Files();
            /* 下面两行用来获取当前时间 */
            Date date = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
            // 将获取来的时间以年月日时分秒的格式添加进实体类中
            files.setTime(dateFormat.format(date));
            files.setUserId(id);
            files.setFile(url);
            int insert = filesDao.insert(files);
            CommonResult commonResult = new CommonResult(200, "success", insert);
            return commonResult;
        } else {
            CommonResult commonResult = new CommonResult(200, "success", "简历已投递,请不要重复投递");
            return commonResult;
        }
    }

    // 根据用户id删除简历
    public int deleteByUserId(Long user_id) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id", user_id);
        int delete = filesDao.delete(queryWrapper);
        return delete;
    }


    // 根据简历id删除简历
    public CommonResult deleteFromFiles(Long id) {
        // 删除进行是否审核的判断，未审核状态下可以删除，已审核状态下不能进行删除
        Files files = filesDao.selectById(id);
        if (files.getFileResult() == 0) {
            // 未处理状态下可以进行删除
            int result = filesDao.deleteById(id);
            CommonResult commonResult = new CommonResult(200, "success", result);
            return commonResult;
        } else {
            CommonResult commonResult = new CommonResult(200, "success", "简历已被处理，无法进行删除操作");
            return commonResult;
        }

    }


    // 根据简历id审核简历
    public CommonResult updateFiles(Long id, int fileResult) {
        // 创建简历实体类用于修改数据
        Files files = new Files();
        /* 下面两行用来获取当前时间 */
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
        files.setId(id);
        files.setCheckTime(dateFormat.format(date));
        files.setFileResult(fileResult);
        filesDao.updateById(files);
        CommonResult commonResult = new CommonResult(200, "success", "审核成功");
        return commonResult;
    }


    // 简历列表
    public CommonResult fileList(String fileDto) throws Exception {
        // 这行代码创建了一个 ObjectMapper 对象，它是 Jackson 库中的核心类，用于进行 JSON 的序列化和反序列化操作。
        ObjectMapper objectMapper = new ObjectMapper();
        // 这行代码通过 ObjectMapper 获取一个 TypeFactory 对象，用于创建 Java 泛型类型的实例。
        TypeFactory typeFactory = objectMapper.getTypeFactory();
        // 这行代码使用 TypeFactory 创建了一个泛型类型 JavaType，其中 PaginationDTO.class 是泛型类的原始类型，YourEntityClass.class 是泛型类型参数。
        JavaType javaType = typeFactory.constructParametricType(PaginationDTO.class, Files.class);
        // 这行代码使用 ObjectMapper 的 readValue 方法，将 JSON 字符串 dataParam 反序列化为 PaginationDTO<YourEntityClass> 类型的对象。
        PaginationDTO<Files> paginationDTO = objectMapper.readValue(fileDto, javaType);
        // 从paginationDTO中获取下面代码需要的数据
        Integer currentPage = paginationDTO.getCurrentPage();
        Integer pageSize = paginationDTO.getPageSize();
        Files file = paginationDTO.getEntity();
        // 根据用户名去查询用户id时的条件
        LambdaQueryWrapper<User> userLqw = new LambdaQueryWrapper<>();
        // 分页查询时的条件
        LambdaQueryWrapper<Files> lqw = new LambdaQueryWrapper<>();
        // 判断前端是否传过来的有实体类的数据
        if (file != null) {
            // 添加查询用户id的条件
            userLqw.like(Strings.isNotEmpty(file.getName()), User::getRealName, file.getName());
            // 根据条件进行查询
            List<User> users = userDao.selectList(userLqw);
            // 创建list集合用于存储用户的id
            List<Long> list = new ArrayList<>();
            // 对查询出来的用户结果进行遍历，取出用户id装到list集合中去
            users.forEach(user -> {
                list.add(user.getId());
            });
            // 若查询没有结果 即list里面为空的话手动设置一个不存在的id使下面的分页条件查询没有结果
            if (list.size() == 0) {
                list.add(999999999999999999L);
            }
            // 添加条件查询的条件
            lqw.in(list != null && list.size() > 0, Files::getUserId, list)
                    .eq(file.getFileResult() != null, Files::getFileResult, file.getFileResult());
        }
        // 查询结果根据建立的状态进行排序（未审核的在最上面，然后依次是什么过的和不通过的）
        lqw.orderByAsc(Files::getFileResult);
        // 封装分页查询的页码和当前的页数
        IPage<Files> page = new Page(currentPage, pageSize);
        // 进行分页条件查询
        IPage<Files> filesIPage = filesDao.selectPage(page, lqw);
        filesIPage.getRecords().forEach(files -> {
            // 对分页条件查询的结果进行遍历，通过其中的用户id去用户表中查出哟个户名和专业，封装到file里面一起进行返回
                    User user = userDao.selectById(files.getUserId());
                    files.setName(user.getRealName());
                    files.setProfession(user.getProfession());
                }
        );
        CommonResult commonResult = new CommonResult(200, "success", page);
        return commonResult;
    }


}
